{% extends "myhome_base.html" %}

{% load seahub_tags avatar_tags i18n upload_tags %}

{% block sub_title %}{{repo.name}} - {% endblock %}
{% block extra_style %}
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/select2.css?t=1393578720" />
<style type="text/css">
#footer { display:none; }
{% if repo.encrypted and repo.enc_version == 2 and not server_crypto %}
#main { display:none; }
{% endif %}
</style>    
<!-- Shim to make HTML5 elements usable in older Internet Explorer versions -->
<!--[if lt IE 9]><script src="{{ MEDIA_URL}}js/html5shiv.js"></script><![endif]-->
{% endblock %}

{% block main_panel %}
    <div id="repo-top">
        <h2 class="hd">{{repo.props.name}}{% if user_perm == 'r' %} <span class="tip vam">({% trans "Read-Only" %})</span>{% endif %}</h2>
            <div id="repo-basic-info">
                <span class="desc" title="{{repo.props.desc}}">{{ repo.props.desc|truncatechars:25 }}</span>
                <span class="size split">{% trans 'Size: ' %}{{ repo_size|filesizeformat }}</span>
                {% if show_repo_download_button or show_repo_settings or user_perm == 'rw' %}
                <span class="split">
                    {% if show_repo_download_button %}
                    <a href="{{ SITE_ROOT }}seafile_access_check/?repo_id={{repo.props.id}}" target="_blank">{% trans "Download" %}</a>
                    {% endif %}
                    {% if show_repo_settings %}
                    <a id="repo-setting-btn" href="{% url 'repo_settings' repo.id %}" class="normal"><img class="link-icon vam" src="{{ MEDIA_URL }}img/setting.png" alt="" /><span class="vam">{% trans "Settings" %}</span></a>
                    {% endif %}
                    {% if user_perm == 'rw' %}
                    <a id="recycle-btn" href="{% url 'repo_recycle_view' repo.id %}" class="normal"><img class="link-icon vam" src="{{ MEDIA_URL }}img/lib_trash.png" alt="" /><span class="vam">{% trans "Trash"%}</span></a>
                    {% endif %}
                </span>
                {% endif %}
            </div>
    </div>

    {% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
    <div id="repo-file-list"></div>
    {% else %}
    <div id="repo-file-list">
        {% include 'snippets/repo_dir_data.html' %}
    </div>
    {% endif %}

    <!-- popups -->
    {% if user_perm == 'rw' %}
    <div id="dirents-op" class="hide">
        <button id="del-dirents" title="{% trans "Delete"%}" class="op-icon-btn"><span class="icon-trash"></span></button>
        <button id="mv-dirents" title="{% trans "Move"%}" class="op-icon-btn"><span class="icon-move"></span></button>
        <button id="cp-dirents" title="{% trans "Copy"%}" class="op-icon-btn"><span class="icon-copy"></span></button>
    </div>
    {% endif %}

    <div id="upload-file-dialog" class="hide">
        {% if no_quota %}
        <h3>{% trans "Upload Files" %}</h3>
        <p class="error">{% trans "The owner of this library has run out of space." %}</p>

        {% else %}

            {% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
            <form id="upload-file-form" enctype="multipart/form-data" method="post" action="">{% csrf_token %}
                <h3>{% trans "Upload Files" %}</h3>
                <input type="file" name="file" /><br />
                <p class="error hide">{% trans "Please select a file at first." %}</p>
                <input type="button" value="{% trans "Submit" %}" />
            </form>

            {% else %}
            <h3 class="hd"><span class="status">{% trans "File Upload" %}</span> <span class="total-progress hide"></span></h3>
            <div class="ops">
                <img src="{{MEDIA_URL}}img/minus.png" alt="" class="fold-switch cspt" />
                <img src="{{MEDIA_URL}}img/close.png" alt="close" title="{% trans "close" %}" class="close cspt hide" />
            </div>
            <div class="con">
                <div class="row fileupload-buttonbar">
                    <button type="button" class="cancel cspt fright">{% trans "Cancel All" %}</button>
                </div>
                <p class="saving-tip alc clear hide"><img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" style="margin-right:5px;" class="vam" />{% trans "Saving..." %}</p>
                <table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
            </div>
           {% endif %} 
        {% endif %}
    </div>

    <div id="update-file-dialog" class="hide">
        <h3 class="hd">{% trans "Update %(file_name)s" %}</h3>
        {% if no_quota %}
        <p class="error">{% trans "The owner of this library has run out of space." %}</p>
        {% else %}      
        <form id="update-file-form" enctype="multipart/form-data" method="post" action="">{% csrf_token %}
            <input type="hidden" name="target_file" />

            {% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
            <input type="file" name="file" /><br />
            <p class="error hide">{% trans "Please select a file at first." %}</p>
            <input type="button" value="{% trans "Submit" %}" />
            {% else %}

            <div class="fileupload-buttonbar">
                <span class="fileinput-button vam">
                    <span>{% trans "Choose a file" %}</span>
                    <input type="file" name="file" />
                </span>
                {% if max_upload_file_size %}
                <span class="vam">({% blocktrans with max_file_size=max_upload_file_size|filesizeformat %}Smaller than {{ max_file_size }}{% endblocktrans %})</span>
                {% endif %}
                <div class="fileupload-progress fade">
                    <div class="progress progress-success progres-striped active">
                        <div class="bar" style="width:0%"></div>
                    </div>
                    <div class="progress-extended"></div>
                </div>
                <p class="saving-tip alc hide"><img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" style="margin-right:5px;" class="vam" />{% trans "Saving..." %}</p>
            </div>
            <table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
            {% endif %}
        </form>
        {% endif %}
    </div>

    <form id="add-new-dir-form" action="" method="post" class="hide">{% csrf_token %}
        <h3>{% trans "New Directory" %}</h3>
        <label>{% trans "Directory Name" %}</label><br /><!-- <br/> for ie 7 -->
        <input type="text" name="name" value="" class="input" maxlength="{{max_file_name}}"/><br />
        <p class="error hide"></p>
        <input type="submit" value="{% trans "Submit" %}" class="submit" />
        <button class="simplemodal-close">{% trans "Cancel" %}</button>
    </form>

    <form id="add-new-file-form" action="" method="post" class="hide">{% csrf_token %}
        <h3>{% trans "New File" %}</h3>
        <div id="featured-filetype">
            <label>{% trans "Featured File Type" %}</label><br />
            <button type="button" class="set-file-type" data-filetype="seaf" title="{% trans "Click to choose" %}">seaf</button> <span>{% trans "online Rich Text format." %}</span>
            {% if LANGUAGE_CODE == 'zh-cn' %}
            <a href="http://www.seafile.com/help/seaf/" target="_blank">{% trans 'Details' %}</a><br /> 
            {% else %}
            <a href="http://www.seafile.com/en/help/seaf/" target="_blank">{% trans 'Details' %}</a><br /> 
            {% endif %}
            <button type="button" class="set-file-type" data-filetype="md" title="{% trans "Click to choose" %}">markdown</button> <span>{% trans "simple markup format." %}</span>
            {% if LANGUAGE_CODE == 'zh-cn' %}
            <a href="http://www.seafile.com/help/markdown/" target="_blank">{% trans 'Details' %}</a>            
            {% else %}
            <a href="http://www.seafile.com/en/help/markdown/" target="_blank">{% trans 'Details' %}</a>            
            {% endif %}
        </div>
        <label>{% trans "File Name" %}</label><br/>
        <input type="text" name="name" value="" class="input" maxlength="{{max_file_name}}"/><br />
        <p class="error hide"></p>
        <input type="submit" value="{% trans "Submit"%}" class="submit" />
        <button class="simplemodal-close">{% trans "Cancel"%}</button>
    </form>

    <form id="mv-form" action="" method="post" class="file-choose-form hide">{% csrf_token %}
        <div id="mv-dir-list" class="dir-tree-cont">
            <h5 class="hd cspt"><span class="icon-caret-down"></span>{% trans "Current Library"%}</h5>
            <img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" class="loading-tip" />     
            <div id="current-repo-dirs"></div>
            {% if not repo.encrypted %}
            <h5 class="hd cspt"><span class="icon-caret-right"></span>{% trans "Other Libraries"%}</h5>
            <img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" class="loading-tip" style="display:none;" />     
            <div id="other-repos-dirs" class="hide"></div>
            {% endif %}
        </div>
        <input type="hidden" name="obj_name" value="" />
        <input type="hidden" name="obj_type" value="" />
        <input type="hidden" name="op" value="" />
        <input type="hidden" name="dst_repo" value="" />
        <input type="hidden" name="dst_path" value="" />
        <p class="error hide">{% trans "Please click and choose a directory."%}</p>
        <button type="submit" class="submit">{% trans "Submit" %}</button>
        <button class="simplemodal-close">{% trans "Cancel"%}</button>
    </form>

    <div id="mv-progress-popup" class="alc hide">
        <p id="mv-details"></p>
        <div id="mv-progress"></div>
        <p id="mv-other-info" class="hide"></p>
        <button id="cancel-mv">{% trans "Cancel" %}</button>
    </div>

    <form id="rename-form" action="" method="post" class="hide">{% csrf_token %}
        <p class="detail">{% trans "Rename %(name)s as:" %}</p>
        <input type="hidden" name="oldname" value="" />
        <input type="text" name="newname" value="" class="input" maxlength="{{max_file_name}}"/><br />
        <p class="error hide"></p>
        <input type="submit" value="{% trans "Submit"%}" class="submit" />
        <button class="simplemodal-close">{% trans "Cancel"%}</button>
    </form>
    
    {% include "snippets/file_share_popup.html" %}

    {% with attach_type='dir' %}
    {% include "snippets/group_recommend_form.html" %}
    {% endwith %}

    {% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
    <form id="repo-decrypt-form" class="wide-panel hide">
        <p>{% trans "This library is encrypted. Please input the password if you want to browse it online. And the password will be kept in the browser for only 1 hour." %}</p>
        <label>{% trans "Password: " %}</label>
        <input type="password" name="password" autofocus />
        <input type="submit" value="{% trans "Submit" %}" />
        <p class="error hide"></p>
        {% url 'edit_profile' as profile_edit_url %}
        <p class="tip" style="margin-top:3em;">{% blocktrans %}You can change how to view encrypted libraries online <a class="normal" href="{{ profile_edit_url }}#enc-lib-setting">here</a>.{% endblocktrans %}</p>
    </form>
    {% endif %}

    <div id="side-toolbar">
        <ul class="side-toolbar">
            {% if groups %}
            <li class="item" id="discuss" title="{% trans "Discussion" %}"><img src="{{MEDIA_URL}}img/discuss.png" alt="{% trans "discuss" %}" /></li>
            <li id="click-into-group" class="item" title="{% trans "Go to a group" %}"><img src="{{MEDIA_URL}}img/groups.png" alt="{% trans "group" %}" /></li>
            {% endif %}
        </ul>
    <div>

    {% if groups|length > 1 %}
    <div id="to-group" class="hide">
        <h3>{% trans "Groups" %}</h3>
        {{ repo_group_str }}
        <div class="outer-caret"><div class="inner-caret"></div></div>
    </div>
    {% endif %}

{% endblock %}

{% block extra_script %}
{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
<script type="text/javascript" src="{{MEDIA_URL}}js/repo_crypto.js"></script>
{% else %}
    {% if not no_quota and user_perm == 'rw' %}
{% upload_js %}
<script type="text/javascript">
function addFile(file_data) {
    var now = parseInt(new Date().getTime()/1000);
    var cur_files = $('.file-item');
    if (cur_files.length == 0) { // there is no file before this upload
        reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path));
    } else {
        var file_tpl = $(cur_files[0]);
        var path = cur_path;
        var new_name = file_data.name;
        var new_file = file_tpl.clone(true);

        new_file.attr({
                'data-name': new_name,
                'data-time': now
                });
        $('.file-star', new_file).attr({
                'title': "{% trans "unstarred" %}",
                'class': 'icon-star-empty file-star',
                'data-status': 'unstarred'
                });
        $('.dirent-icon img', new_file).attr('src', '{{MEDIA_URL}}img/file/file.png');
        $('.dirent-name a', new_file).html(new_name).attr('href', '{% url 'repo_view_file' repo.id %}?p=' + e(path+new_name));
        $('.dirent-size', new_file).html(filesizeformat(file_data.size, 1));
        $('.dirent-update', new_file).html("{% trans "Just now" %}");
        $('.file-download', new_file).attr('href', '{{SITE_ROOT}}repo/{{repo.id}}/' + file_data.id + '/download/?p=' + e(path+new_name));
        $('.file-share', new_file).attr({
                'data-link': '',
                'data-token': ''
                });
        $('.file-history', new_file).attr('href', '{% url 'file_revisions' repo.id %}?p=' + e(path+new_name));
        file_tpl.before(new_file);
        updateCmt();
    }
}

$(function() {
    $.getScript('{{ MEDIA_URL }}js/jquery.fileupload.min.js', function () {
        var popup = $('#upload-file-dialog').addClass('fixed-upload-file-dialog');;
        var popup_height = '200px';
        popup.css({'height': popup_height}).data('height', popup_height);

        var fu_status = $('.status', popup),
            total_progress = $('.total-progress', popup),
            cancel_all_btn = $('.fileupload-buttonbar .cancel', popup),
            close_icon = $('.close', popup),
            saving_tip = $('.saving-tip', popup);

        var fu_status_ = {
            'uploading': "{% trans "File Uploading..." %}",
            'complete': "{% trans "File Upload complete" %}",
            'canceled': "{% trans "File Upload canceled" %}",
            'failed': "{% trans "File Upload failed" %}"
        };

        var dirs_to_update = []; // dirs with 'time' to be updated
        var new_dir_names = [];
        popup.fileupload({
            formData: {'parent_dir': cur_path},
            fileInput: $('#upload-file input'),
            paramName: 'file',
            // customize it for 'done'
            getFilesFromResponse: function (data) {
                if (data.result) {
                    return data.result;
                }
            },
            autoUpload:true,
            {% if max_upload_file_size %}
            maxFileSize: {{ max_upload_file_size }}, // in bytes
            {% endif %}
            maxNumberOfFiles: 500,
            sequentialUploads: true
        })
        .bind('fileuploadadd', function(e, data) {
            popup.removeClass('hide');
            cancel_all_btn.removeClass('hide');
            close_icon.addClass('hide');

            {% if enable_upload_folder %}
            // hide the upload menu
            if (!$('#upload-menu').hasClass('hide')) {
                $('#upload-menu').find('.item').removeAttr('style')
            .end().addClass('hide');
            }

            // when add folder, a subdirectory will be shown as '.'. rm it.
            var file = data.files[0];
            if (file.name == '.') {
                data.files.shift();
            }
            if (file.webkitRelativePath) { // for 'upload folder'
                file.relative_path = file.webkitRelativePath;
            }
            if (file.relativePath) { // for 'folder drag & drop'
                file.relative_path = file.relativePath + file.name;
            }
            {% endif %}
        })
        .bind('fileuploadstart', function() {
            fu_status.html(fu_status_.uploading);
        })
        .bind('fileuploadsubmit', function(e, data) {
            var _this = $(this);
            var file = data.files[0];
            // get url(token) for every file
            if (!file.error) {
                $.ajax({
                    url: '{% url 'get_file_op_url' repo.id %}?op_type=upload',
                    cache: false,
                    dataType: 'json',
                    success: function(ret) {
                        {% if enable_upload_folder %}
                        var file_path = file.relative_path,
                            r_path;
                        if (file_path) { // 'add folder'
                            r_path = file_path.substring(0, file_path.lastIndexOf('/') + 1);
                        }
                        var formData = popup.fileupload('option', 'formData');
                        formData.relative_path = r_path || '';
                        popup.fileupload('option', 'formData', formData);
                        {% endif %}

                        data.url = ret['url'];
                        data.jqXHR = _this.fileupload('send', data);
                    },
                    error: function() {
                        file.error = "{% trans "Failed to get upload url" %}";
                    }
                });
                return false;
            }
        })
        .bind('fileuploadprogressall', function (e, data) {
            total_progress.html(parseInt(data.loaded / data.total * 100, 10) + '% ' + '<span style="font-size:14px;color:#555;">(' + $(this).data('blueimp-fileupload')._formatBitrate(data.bitrate) + ')</span>').removeClass('hide');
            if (data.loaded > 0 && data.loaded == data.total) {
                saving_tip.show();
            }
        })
        .bind('fileuploaddone', function(e, data) {
            if (data.textStatus != 'success') {
                return;
            }
            var file = data.files[0];
            var file_path = file.relative_path;
            var file_uploaded = data.result[0]; // 'id', 'name', 'size'

            // for 'template_download' render
            file_uploaded.uploaded = true;
            if (file_path) {
                file_uploaded.relative_path = file_path.substring(0, file_path.lastIndexOf('/') + 1) + file_uploaded.name;
            }

            if (data.formData.parent_dir != cur_path) {
                return;
            }
            if (!file_path) {
                addFile(file_uploaded);
                return;
            }

            {% if enable_upload_folder %}
            // for 'add folder'
            var cur_dirs = $('.dir-item');
            var cur_dir_names = [];
            cur_dirs.each(function() {
                cur_dir_names.push($(this).attr('data-name'));
            });

            var new_dir_name = file_path.substring(0, file_path.indexOf('/'));
            if (cur_dir_names.indexOf(new_dir_name) == -1) {
                if (new_dir_names.indexOf(new_dir_name) == -1) {
                    new_dir_names.push(new_dir_name);
                }
            } else {
                if (dirs_to_update.indexOf(new_dir_name) == -1) {
                    dirs_to_update.push(new_dir_name);
                }
            }
            {% endif %}
        })
        .bind('fileuploadstop', function() {
            cancel_all_btn.addClass('hide');
            close_icon.removeClass('hide');
            if (popup.fileupload('option','formData').parent_dir != cur_path) {
                return;
            }
            var now = parseInt(new Date().getTime()/1000);
            var cur_dirs = $('.dir-item');
            if (new_dir_names.length > 0) {
                if (cur_dirs.length == 0) {
                    reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path));
                    return;
                } else {
                    var dir_tpl = $(cur_dirs[0]);
                    var path = cur_path;
                    $(new_dir_names).each(function(index, new_dir_name) {
                        var new_dir = dir_tpl.clone(true);
                        new_dir.attr({
                            'data-name': new_dir_name,
                            'data-time': now
                        });
                        $('.dirent-name a', new_dir).html(new_dir_name).attr('href', '{% url 'repo' repo.id %}?p=' + e(path+new_dir_name));
                        $('.dirent-update', new_dir).html("{% trans "Just now" %}");
                        $('.dir-download', new_dir).attr('href', '{% url 'repo_download_dir' repo.id %}?p=' + e(path+new_dir_name));
                        $('.dir-share', new_dir).attr({
                            'data-link':'',
                            'data-token':'',
                            'data-upload-link':'',
                            'data-upload-token':''
                        });
                        dir_tpl.before(new_dir);
                    });
                    updateCmt();
                }
            }
            if (dirs_to_update.length > 0) {
                cur_dirs.each(function() {
                    var dir = $(this);
                    if (dirs_to_update.indexOf(dir.attr('data-name')) != -1) {
                        dir.attr('data-time', now);
                        $('.dirent-update', dir).html("{% trans "Just now" %}");
                    }
                });
                updateCmt();
            }
            // empty the arrays
            new_dir_names = [];
            dirs_to_update = [];
        })
        // after tpl has rendered
        .bind('fileuploadcompleted', function() { // 'done'
            if ($('.files .cancel', popup).length == 0) {
                saving_tip.hide();
                total_progress.addClass('hide');
                fu_status.html(fu_status_.complete);
            }
        })
        .bind('fileuploadfailed', function(e, data) { // 'fail'
            if ($('.files .cancel', popup).length == 0) {
                cancel_all_btn.addClass('hide');
                close_icon.removeClass('hide');
                total_progress.addClass('hide');
                saving_tip.hide();
                if (data.errorThrown == 'abort') { // 'cancel'
                    fu_status.html(fu_status_.canceled);
                } else { // 'error'
                    fu_status.html(fu_status_.failed);
                }
            }
        });

        // Enable iframe cross-domain access via redirect option:
        popup.fileupload(
            'option',
            'redirect',
            window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '{{ MEDIA_URL }}cors/result.html?%s')
        );
    });
});

// fold/unfold the dialog
$('#upload-file-dialog .fold-switch').click(function() {
    var popup = $('#upload-file-dialog');
    var full_ht = parseInt(popup.data('height'));
    var main_con = $('.fileupload-buttonbar, .table', popup);
    if (popup.height() == full_ht) {
        popup.height($('.hd', popup).outerHeight(true));
        main_con.addClass('hide');
    } else {
        popup.height(full_ht);
        main_con.removeClass('hide');
    }
});
$('#upload-file-dialog .close').click(function() {
    $('#upload-file-dialog').addClass('hide');
    $('#upload-file-dialog .files').empty();
});

window.locale = { 
    "fileupload": {
        "errors": {
            "maxFileSize": "{% trans "File is too big" %}",
            "minFileSize": "{% trans "File is too small" %}",
            "acceptFileTypes": "{% trans "Filetype not allowed" %}",
            "maxNumberOfFiles": "{% trans "Max number of files exceeded" %}",
            "uploadedBytes": "{% trans "Uploaded bytes exceed file size" %}",
            "emptyResult": "{% trans "Empty file upload result" %}"
        },  
        "error": "{% trans "Error" %}",
        "uploaded": "{% trans "uploaded" %}",
        "canceled": "{% trans "canceled" %}",
        "start": "{% trans "Start" %}",
        "cancel": "{% trans "Cancel" %}",
        "destroy": "{% trans "Delete" %}"
    }   
};
</script>
{% endif %}
{% endif %}
<script type="text/javascript">
$(function() {
    // for file private share
    $.getScript('{{ MEDIA_URL }}js/select2.min.js');
});
// refresh #repo-file-list, and do things needed to do after that.
function reqDirData(url, func) {
    var orig_wtop = $(window).scrollTop();
    $.ajax({
        url: url,
        cache: false,
        dataType: 'json',
        success: function(data) {
            $('#repo-file-list').html(data['html']);
            
            // both original dir list and new dir list are long
            var repo_top = $('#repo-top'),
                h = repo_top.offset().top + repo_top.outerHeight(true);
            if (orig_wtop > h && $(window).scrollTop() == orig_wtop) {
                $(window).scrollTop(h);
            }

            cur_path = data['path']; // update cur_path
            last_start = 0; // for current dir's 'list_dir_more'

            {% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
            {% else %}
                {% if user_perm == 'rw' and not no_quota %}
            $('#upload-file-dialog').fileupload(
                'option',
                {
                    formData: {'parent_dir': cur_path},
                    fileInput: $('#upload-file input')
                }
            );
                {% endif %}
            {% endif %}

            if (func) {
                func(data);
            }
            dirOP();
            // in case the 'discuss' & #dirents-op popup is open before this request
            $('#discuss-to-group, #discuss-to-group-caret, #dirents-op').addClass('hide');
        },
        error:function(xhr, textStatus, errorThrown) {
            if (xhr.responseText) {
                feedback(jQuery.parseJSON(xhr.responseText).err_msg, 'error');
            } else {
                feedback("{% trans "Failed. Please check the network." %}", 'error');
            }
        }
    });
}

{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
// 'passwd' will be kept for 1 hour.
var valid_time_period = 60 * 60 * 1000;
// key, iv used in file encrypt/decrypt
var enc_key, enc_iv;
if ('localStorage' in window && window['localStorage'] !== null) {
    // 'localStorage' is supported
    var last_decrypt_t = localStorage['{{repo.id}}_decrypt_t'];
    // decrypt at the first time, or when last decryption is more than 1 hour ago
    if (!last_decrypt_t || (new Date().getTime() - last_decrypt_t > valid_time_period)) {
        decrypt_repo();
    } else {
        reqDirData('{% url 'repo_dir_data' repo.id %}' + location.search, function() {
            $('#main').show();
        });
        enc_key = localStorage['{{repo.id}}_enc_key'];
        enc_iv = localStorage['{{repo.id}}_enc_iv'];
    }
} else {
    // 'localStorage' is not supported, decrypt every time
    decrypt_repo();
}
function decrypt_repo() {
    var decrypt_form = $('#repo-decrypt-form');
    $('#header').after(decrypt_form.removeClass('hide'));
    $('[type="submit"]', decrypt_form).click(function() {
        var passwd = $('[name="password"]', decrypt_form).val(),
            err = $('.error', decrypt_form);
        if (!$.trim(passwd)) {
            err.html("{% trans "Please enter the password." %}").removeClass('hide');
            return false;
        }
        
        var magic_str = gen_magic_str('{{repo.id}}', passwd);
        if (magic_str == '{{repo.magic}}') {
            decrypt_form.remove();
            reqDirData('{% url 'repo_dir_data' repo.id %}' + location.search, function() {
                $('#main').show();
            });
            
            var fileKey = new FileKey(passwd);
            var file_key = fileKey.decrypt('{{repo.random_key}}');

            var enc_obj = gen_enc_key_iv(file_key);
            enc_key = enc_obj.key;
            enc_iv = enc_obj.iv;
            if ('localStorage' in window && window['localStorage'] !== null) {
                var repo_id = '{{repo.id}}';
                localStorage[repo_id + '_decrypt_t'] = new Date().getTime();
                localStorage[repo_id + '_enc_key'] = enc_key;
                localStorage[repo_id + '_enc_iv'] = enc_iv;
            } 
        } else {
            err.html("{% trans "Wrong password" %}").removeClass('hide');
        }
        return false;
    });
}
{% endif %}

function setDirentsOpPos() {
    var dirents_op = $('#dirents-op');
    dirents_op.css({
        'left': $('#repo-file-list').offset().left - dirents_op.outerWidth(true) - 20,
        'top': $(window).height()/2
    });
}

// del multi dirents
$('#del-dirents').click(function() {
    $('#confirm-popup').modal({appendTo:'#main'});
    $('#simplemodal-container').css({'height':'auto'});
    $('#confirm-con').html('<h3>' + "{% trans "Delete Items" %}" + '</h3><p>' + "{% trans "Are you sure you want to delete these selected items?" %}" + '</p>');
    $('#confirm-yes').unbind().click(del_dirents);
});
var del_dirents = function() {
    $('#confirm-popup').append('<p style="color:red;">' + "{% trans "Processing..." %}" + '</p>');
    var dirents = $('.checkbox-checked').parents('.dir-item, .file-item'),
        dirents_names = [];
    dirents.each(function() {
        dirents_names.push($(this).attr('data-name'));
    });
    $.ajax({
        url: '{% url 'delete_dirents' repo.id %}' + '?parent_dir=' + e(cur_path),
        type: 'POST',
        dataType: 'json',
        beforeSend: prepareCSRFToken,
        traditional: true,
        data: {
            'dirents_names': dirents_names
        },
        success: function(data) {
            var deleted_len = data['deleted'].length,
                msg_s, msg_f;
            
            if (deleted_len > 0) {
                if (deleted_len == dirents_names.length) {
                    dirents.remove();
                } else {
                    dirents.each(function() {
                        if ($(this).data('name') in data['deleted']) {
                            $(this).remove();
                        }
                    }); 
                }
                if (data['deleted'].length > 1) {
                    msg_s = "{% trans "Successfully deleted %(name)s and %(amount)s other items." %}";
                } else {
                    msg_s = "{% trans "Successfully deleted %(name)s." %}";
                }
                msg_s = msg_s.replace('%(name)s', data['deleted'][0]).replace('%(amount)s', data['deleted'].length - 1);
                feedback(msg_s, 'success'); 
                updateCmt();
            }

            if (data['undeleted'].length > 0) {
                if (data['undeleted'].length > 1) {
                    msg_f = "{% trans "Internal error. Failed to delete %(name)s and %(amount)s other items." %}"
                } else {
                    msg_f = "{% trans "Internal error. Failed to delete %(name)s." %}"
                }
                msg_f = msg_f.replace('%(name)s', data['undeleted'][0]).replace('%(amount)s', data['undeleted'].length - 1);
                feedback(msg_f, 'error'); 
            }
            $.modal.close();
            $('#dirents-op').addClass('hide');
            $('th.select .checkbox').removeClass('checkbox-checked');
        },
        error: function(xhr, textStatus, errorThrown) {
            $.modal.close();
            ajaxErrorHandler(xhr, textStatus, errorThrown);
        }
    });
};

// render jstree for current path
function render_jstree_for_cur_path() {
    var form = $('#mv-form'),
        file_tree = new FileTree(),
        container = $('#current-repo-dirs'),
        loading_tip = container.prev();
    container.data('site_root', '{{SITE_ROOT}}');
    $.ajax({
        url: '{% url 'get_dirents' repo.id %}?path=' + e(cur_path) + '&dir_only=true&all_dir=true',
        cache: false,
        dataType: 'json',
        success: function(data) {
            var json_data = [];
            var repo_data = {
                'data': '{{ repo.props.name }}',
                'attr': {'repo_id': '{{ repo.props.id }}', 'root_node': true},
                'state': 'open'
            };

            var path_eles = cur_path.split('/');
            path_eles.pop();
            /* e.g.
             * path: '/xx/'
             * path_eles: ['', 'xx']
             * data: [["xxx", "xx", "test1022"], ["lkjj", "kjhkhi"]]
             * when no dir in '/', data will be [[]];
             */
            var len = data.length;
            var children = [];
            for (var i = len - 1; i > -1; i--) {
                children[i] = [];
                if (i == len - 1) {
                    for (var j = 0, len_i = data[i].length; j < len_i; j++) {
                        children[i].push({
                            'data': data[i][j],
                            'state': 'closed'
                        });
                    }
                } else {
                    for (var j = 0, len_i = data[i].length; j < len_i; j++) {
                        if (data[i][j] == path_eles[i+1]) {
                            children[i].push({
                                'data': data[i][j],
                                'state': 'open',
                                'children': children[i+1] 
                            });
                        } else {
                            children[i].push({
                                'data': data[i][j],
                                'state': 'closed'
                            });
                        }
                    }
                }
            }
            if (children[0].length > 0) {
                $.extend(repo_data, {'children': children[0]});
            }
            json_data.push(repo_data); 

            loading_tip.hide();
            file_tree.renderDirTree(container, form, json_data);
            container.removeClass('hide');
        },
        error: function() {
            var cur_repo = [{
                'data': '{{ repo.props.name }}',
                'attr': {'repo_id': '{{ repo.props.id }}', 'root_node': true},
                'state': 'closed'
            }];
            loading_tip.hide();
            file_tree.renderDirTree(container, form, cur_repo);
            container.removeClass('hide');
        }
    });
}
// mv, cp multi dirents
$('#mv-dirents, #cp-dirents').click(function() {
    var form = $('#mv-form'), op;
    form.modal({appendTo:'#main', autoResize:true, focus:false});
    $('#simplemodal-container').css({'width':'auto', 'height':'auto'});

    if ($(this).attr('id') == 'mv-dirents') {
        op = 'mv';
        form.prepend("<h3>{% trans "Move selected directories/files to:" %}</h3>");
    } else {
        op = 'cp';
        form.prepend("<h3>{% trans "Copy selected directories/files to:" %}</h3>");
    }

    render_jstree_for_cur_path();

    var files = $('.checkbox-checked').parents('.file-item'),
        dirs = $('.checkbox-checked').parents('.dir-item'),
        dir_names = [], file_names = [];

    files.each(function() {
        file_names.push($(this).attr('data-name'));
    });
    dirs.each(function() {
        dir_names.push($(this).attr('data-name'));
    });

    form.submit(function() {
        var dst_repo = $('[name="dst_repo"]', form).val(),
            dst_path = $('[name="dst_path"]', form).val(),
            url_main;

        if (!$.trim(dst_repo) || !$.trim(dst_path)) {
            $('.error', form).removeClass('hide');
            return false;
        }
        if (dst_repo == '{{repo.id }}' && dst_path == cur_path) {
            $('.error', form).html("{% trans "Invalid destination path" %}").removeClass('hide');
            return false;
        }

        disable($('[type="submit"]', form));
        form.append('<p style="color:red;">' + "{% trans "Processing..." %}" + '</p>');

        if (dst_repo == '{{repo.id }}') {
            // when mv/cp in current lib, files/dirs can be handled in batch, and no need to show progress
            url_main = op == 'mv' ? '{% url 'mv_dirents' repo.id %}':'{% url 'cp_dirents' repo.id %}';
            $.ajax({
                url: url_main + '?parent_dir=' + e(cur_path),
                type: 'POST',
                dataType: 'json',
                beforeSend: prepareCSRFToken,
                traditional: true,
                data: {
                    'file_names': file_names,
                    'dir_names': dir_names,
                    'dst_repo': dst_repo,
                    'dst_path': dst_path
                },
                success: function(data) {
                    var success_len = data['success'].length,
                        msg_s, msg_f,
                        view_url = data['url'];

                    $.modal.close();
                    $('#dirents-op').addClass('hide');
                    $('th.select .checkbox').removeClass('checkbox-checked');

                    if (success_len > 0) {
                        if (op == 'mv') {
                            if (success_len == files.length + dirs.length) {
                                files.remove();
                                dirs.remove();
                            } else {
                                files.each(function() {
                                    if ($(this).data('name') in data['success']) {
                                        $(this).remove();
                                    }
                                });
                                dirs.each(function() {
                                    if ($(this).data('name') in data['success']) {
                                        $(this).remove();
                                    }
                                });
                            }
                            if (success_len == 1) {
                                msg_s = "{% trans "Successfully moved %(name)s." %}";
                            } else if (success_len == 2) {
                                msg_s = "{% trans "Successfully moved %(name)s and 1 other item." %}";
                            } else {
                                msg_s = "{% trans "Successfully moved %(name)s and %(amount)s other items." %}";
                            }
                        } else { // cp
                            $('.checkbox').removeClass('checkbox-checked');
                            if (success_len == 1) {
                                msg_s = "{% trans "Successfully copied %(name)s." %}";
                            } else if (success_len == 2) {
                                msg_s = "{% trans "Successfully copied %(name)s and 1 other item." %}";
                            } else {
                                msg_s = "{% trans "Successfully copied %(name)s and %(amount)s other items." %}";
                            }
                        }
                        msg_s = msg_s.replace('%(name)s', data['success'][0]).replace('%(amount)s', data['success'].length - 1);
                        msg_s += ' <a href="' + view_url + '">' + "{% trans "View" %}" + '</a>';
                        feedback(msg_s, 'success');
                        updateCmt();
                    }

                    if (data['failed'].length > 0) {
                        if (op == 'mv') {
                            if (data['failed'].length > 1) {
                                msg_f = "{% trans "Internal error. Failed to move %(name)s and %(amount)s other items." %}";
                            } else {
                                msg_f = "{% trans "Internal error. Failed to move %(name)s." %}";
                            }
                        } else {
                            if (data['failed'].length > 1) {
                                msg_f = "{% trans "Internal error. Failed to copy %(name)s and %(amount)s other items." %}";
                            } else {
                                msg_f = "{% trans "Internal error. Failed to copy %(name)s." %}";
                            }
                        }
                        msg_f = msg_f.replace('%(name)s', data['failed'][0]).replace('%(amount)s', data['failed'].length - 1);
                        feedback(msg_f, 'error');
                    }
                },
                error: function(xhr, textStatus, errorThrown) {
                    $.modal.close();
                    ajaxErrorHandler(xhr, textStatus, errorThrown);
                }
            });
        } else {
            // when mv/cp to another lib, files/dirs should be handled one by one, and need to show progress
            var op_objs = $('.checkbox-checked').parents('.dir-item, .file-item'),
                i = 0;
            // progress popup
            var details = $('#mv-details'),
                cancel_btn = $('#cancel-mv'),
                other_info = $('#mv-other-info');

            var mvcpDirent = function () {
                var op_obj = $(op_objs[i]),
                    obj_type = op_obj.hasClass('dir-item') ? 'dir':'file',
                    obj_name = op_obj.attr('data-name'),
                    post_url;

                if (op == 'mv') {
                    post_url = obj_type == 'dir' ? '{% url 'mv_dir' repo.id %}':'{% url 'mv_file' repo.id %}';
                } else {
                    post_url = obj_type == 'dir' ? '{% url 'cp_dir' repo.id %}':'{% url 'cp_file' repo.id %}';
                }
                post_url += '?path=' + e(cur_path) + '&obj_name=' + e(obj_name);
                post_data = {
                    'dst_repo': dst_repo,
                    'dst_path': dst_path
                };
                var after_op_success = function (data) {
                    var det_text = op == 'mv' ? "{% trans "Moving file %(index)s of %(total)s" %}": "{% trans "Copying file %(index)s of %(total)s" %}";
                    details.html(det_text.replace('%(index)s', i + 1).replace('%(total)s', op_objs.length)).removeClass('vh');
                    cancel_btn.removeClass('hide');
                    var req_progress = function () {
                        var task_id = data['task_id'];
                        cancel_btn.data('task_id', task_id);
                        $.ajax({
                            url: '{% url "get_cp_progress" %}?task_id=' + e(task_id),
                            dataType: 'json',
                            success: function(data) {
                                var bar = $('.ui-progressbar-value', $('#mv-progress'));
                                if (!data['failed'] && !data['canceled'] && !data['successful']) {
                                    setTimeout(req_progress, 1000);
                                } else {
                                    if (data['successful']) {
                                        bar.css('width', parseInt((i + 1)/op_objs.length*100, 10) + '%').show();
                                        if (op=='mv') {
                                            op_obj.remove();
                                            updateCmt();
                                        }
                                        endOrContinue();
                                    } else { // failed or canceled
                                        if (data['failed']) {
                                            var error_msg = op == 'mv' ? 'Failed to move %(name)s':'Failed to copy %(name)s';
                                            cancel_btn.after('<p class="error">' + error_msg.replace('%(name)s', obj_name) + '</p>');    
                                            end();
                                        }
                                    }
                                }
                            },
                            error: function(xhr, textStatus, errorThrown) {
                                var error;
                                if (xhr.responseText) {
                                    error = $.parseJSON(xhr.responseText).error;
                                } else {
                                    error = "{% trans "Failed. Please check the network." %}";
                                }
                                cancel_btn.after('<p class="error">' + error + '</p>');    
                                end();
                            }
                        });
                    }; // 'req_progress' ends
                    if (i == 0) {
                        $.modal.close();
                        $('#dirents-op').addClass('hide');
                        setTimeout(function () {
                            $('#mv-progress-popup').modal({containerCss: {
                                width: 300,
                                height: 150,
                                paddingTop: 50
                            }, focus:false});
                            $('#mv-progress').progressbar();
                            req_progress();
                        }, 100);
                    } else {
                        req_progress();
                    }
                }; // 'after_op_success' ends
                ajaxPost({
                    'form': form,
                    'post_url': post_url,
                    'post_data': post_data,
                    'after_op_success': after_op_success,
                    'form_id': form.attr('id')
                });
            }; // 'mvcpDirent' ends
            var endOrContinue = function () {
                if (i == op_objs.length - 1) {
                    setTimeout(function () { $.modal.close(); }, 500);
                } else {
                    mvcpDirent(++i);
                }
            };
            var end = function () {
                setTimeout(function () { $.modal.close(); }, 500);
            };
            mvcpDirent();
            cancel_btn.click(function() {
                disable(cancel_btn);
                var task_id = $(this).data('task_id');
                $.ajax({
                    url: '{% url "cancel_cp" %}?task_id=' + e(task_id),
                    dataType: 'json',
                    success: function(data) {
                        other_info.html("{% trans "Canceled." %}").removeClass('hide');
                        cancel_btn.addClass('hide');
                        end();
                    },
                    error: function(xhr, textStatus, errorThrown) {
                        var error;
                        if (xhr.responseText) {
                            error = $.parseJSON(xhr.responseText).error;
                        } else {
                            error = "{% trans "Failed. Please check the network." %}";
                        }
                        other_info.html(error).removeClass('hide');
                        enable(cancel_btn);
                    }
                });
            });
        }
        return false;
    });
});

{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
function showMsg(con, type) {
    if ($('.messages')[0]) {
        $('.messages').html('<li class="' + type + '">' + con + '</li>');
    } else {
        var html = '<ul class="messages"><li class="' + type + '">' + con + '</li></ul>';
        $('#main').append(html);
    }   
    $('.messages').css({'left':($(window).width() - $('.messages').width())/2, 'top':10}).removeClass('hide');
}

function wordArray2ab(wordArray) {
    // Shortcuts
    var words = wordArray.words;
    var sigBytes = wordArray.sigBytes;

    // Convert
    var u8 = new Uint8Array(sigBytes);
    for (var i = 0; i < sigBytes; i++) {
        var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
        u8[i] = byte;
    }

    return u8;
}

function encAndSubmitFile(file, fd, submit_url) {
    function sliceFile(file) {
        file.slice = file.mozSlice || file.webkitSlice || file.slice; // compatibility
        var pos = 0;
        var slices = [];
        while(pos < file.size){
          slices.push(file.slice(pos, pos += 1024 * 1024));
        }     
        return slices;
    }
    var blocks = sliceFile(file), encrypted_blocks = [];

    // file.size is 0, do not encrypt
    if (blocks.length == 0) {
        onFinish();
        return;
    }
    showMsg("{% trans "Encrypting the file..." %}", 'info');

    var workers = [], workersCount = 4, i, len;
    for (i = 0; i < workersCount; i++) {
        workers.push(new Worker('{{MEDIA_URL}}js/file_crypto.js'));
    }
    for (i = 0, len = workers.length; i < len ; i++) {
        workers[i].addEventListener('message', onWorkerMessage, false);
    } 
    for (i = 0, len = blocks.length; i < len; i++) {
        workers[i % workers.length].postMessage({
            encrypt: true,
            key: enc_key,
            iv: enc_iv,
            index: i,
            block: blocks[i]
        });
    }

    function onWorkerMessage(e) {
        if (typeof e.data != 'object') {
            // error
            showMsg("{% trans "Error when encrypting." %}", 'error');
            //console.log('error block index:' + e.data);
            setTimeout(function() { $('.messages').addClass('hide'); }, 1000);
            return;
        }

        encrypted_blocks.push({index: e.data.index, block: e.data.block, block_id: e.data.block_id}); 
        var msg = "{% trans "Encrypting, %(num)s% complete." %}";
        showMsg(msg.replace('%(num)s', (encrypted_blocks.length / blocks.length * 100).toFixed(0)), 'info');
        if (encrypted_blocks.length == blocks.length ) {
            onFinish();
        }
    }

    function onFinish() {
        var ordered_enc_blocks = [], blk;
        for (var i = 0, len = encrypted_blocks.length; i < len; i++) {
             ordered_enc_blocks[encrypted_blocks[i].index] = {'id': encrypted_blocks[i].block_id, 'block': encrypted_blocks[i].block};
        } 
        for (var i = 0, len = ordered_enc_blocks.length; i < len; i++) {
            blk = new Blob([wordArray2ab(ordered_enc_blocks[i].block)], {type:''});
            fd.append('file', blk, ordered_enc_blocks[i].id);
        }

        showMsg("{% trans "Uploading ..." %}", 'info');
        $.ajax({
            url: submit_url,
            type: "POST",
            dataType: 'json',
            data: fd,
            processData: false,  // tell jQuery not to process the data
            contentType: false, // tell jQuery not to set contentType
            beforeSend: prepareCSRFToken,
            success: function(data) {
                $.modal.close();
                reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path));
                showMsg("{% trans "Done!" %}", 'info');
                setTimeout(function() { $('.messages').addClass('hide'); }, 1500);
            },
            error: function () {
                $.modal.close();
                feedback("{% trans "Failed." %}", 'error');
            }
        });
    }
}
{% endif %}

// js on repo file list
var no_file_op_popup = true;

function setPathWidth() {
    $('.path').width($('.repo-file-list-topbar').width() - $('.repo-op').width() - 20);
}
$(function () { setPathWidth(); });

{% include "snippets/list_commit_detail.html" %}

function dirOP() {

setPathWidth();

$('.path .dir-link').click(dirlinkClick);

$('.lsch').unbind().click(function() {
    listCommitDetails($(this).data('url'), $(this).data('time'));
    return false;
}); 

{% if user_perm == 'rw' %}
{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
$('#upload-file').click(function () {
    $('#upload-file-dialog').modal();
    $('#simplemodal-container').css({'height':'auto'});

    $('#upload-file-form [type="button"]').click(function() {
        var form = $('#upload-file-form');
        var file_input = $('[type="file"]', form);
        if (file_input[0].files.length == 0) {
            $('.error', form).removeClass('hide');
            return false;
        }
        var file = file_input[0].files[0];
        
        // prepare fd
        file_input.remove();// the selected file will not be submitted
        var fd = new FormData(form[0]);// get the fields in the form (e.g. csrf...token)
        fd.append('parent_dir', cur_path);
        fd.append('file_name', file.name);
        fd.append('file_size', file.size);

        $.modal.close();
        $.ajax({
            url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('upload-blks'),
            cache: false,
            dataType: 'json',
            success: function(data) {
                encAndSubmitFile(file, fd, data['url']);
            },
            error: ajaxErrorHandler
        });
    });
});
{% else %}
    {% if no_quota %}
$('#upload-file').click(function () {
    $('#upload-file-dialog').modal();
});
    {% else %}
        {% if enable_upload_folder %}
    if ('webkitdirectory' in $('#upload-file input[type="file"]')[0]) {
        $('#upload-file').find('input').remove().end().addClass('cspt');
        $('#upload-menu .item').click(function() {
            $('#upload-file-dialog').fileupload(
                'option',
                'fileInput',
                $('input[type="file"]', $(this))
            );
        })
        .hover(
            function() {
                $(this).css({'background':'#f3f3f3'});
            },
            function() {
                $(this).css({'background':'transparent'});
            }
        );
        $('.repo-op').css({'position': 'relative'});
        $('#upload-file').click(function () {
            $('#upload-menu').toggleClass('hide');
        });
        $(document).click(function(e) {
            var target = e.target || event.srcElement;
            var closePopup = function(popup, popup_switch) {
                if (!popup.hasClass('hide') && !popup.is(target) && !popup.find('*').is(target) && !popup_switch.is(target) && !popup_switch.find('*').is(target) ) {
                    popup.addClass('hide');
                }
            };
            closePopup($('#upload-menu'), $('#upload-file'));
        });
    }
        {% endif %}
    {% endif %}
{% endif %}

$('#add-new-dir').click(function () {
    $('#add-new-dir-form').modal({appendTo:'#main'});
    $('#simplemodal-container').css({'height':'auto'});
});
  
$('#add-new-file').click(function () {
    $('#add-new-file-form').modal({appendTo:'#main', focus:false, containerCss:{'padding':'20px 25px'}});
    $('#simplemodal-container').css({'height':'auto'});
});
{% endif %} {# user_perm == 'rw' #}

// share current dir
$('#share-cur-dir').click(function() {
   var op = $(this), name, aj_urls, type;
   name = $('#cur-dir-name').html();
   aj_urls = { 'link': op.data('url'), 'upload-link': op.data('upload-url') };
   type = 'd';
   showSharePopup(op, name, aj_urls, type, cur_path);
});

//select all or not
$('th .checkbox-orig').unbind().click(function() {
    var dirents_op = $('#dirents-op');

    var checkbox =  $(this).parent();
    checkbox.toggleClass('checkbox-checked');

    if (checkbox.hasClass('checkbox-checked')) {
        $('.checkbox').addClass('checkbox-checked');
    } else {
        $('.checkbox').removeClass('checkbox-checked');
    }

    // show buttons or not
    if ($('.checkbox-checked', $('.dir-item, .file-item')).length > 0) {
        dirents_op.removeClass('hide');
        setDirentsOpPos();
    } else {
        dirents_op.addClass('hide');
    }
});

//sort
$('#name-down, #name-up, #time-up, #time-down').click(sortDirent);

$('.dir-item, .file-item').unbind().hover( // remove previously binded hover handler at first
    function() {
        if (no_file_op_popup) {
            $(this).addClass('hl').find('.repo-file-op').removeClass('vh');
        }
    },
    function() {
        if (no_file_op_popup) {
            $(this).removeClass('hl').find('.repo-file-op').addClass('vh');
        }
    }
);

opOnDirent();

} // function dirOP ends here

dirOP();

function sortDirent() {
    var id= $(this).attr('id'), by,
        dir_list = [], file_list = [],
        table = $('.repo-file-list');
    
    switch (id) {
        case 'name-down': by = function(a, b) { return a.name.toLowerCase() < b.name.toLowerCase() ? 1 : -1 };break;
        case 'name-up': by = function(a, b) { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1 };break;
        case 'time-up': by = function(a, b) { return a.time < b.time ? -1 : 1 };break;
        case 'time-down': by = function(a, b) { return a.time < b.time ? 1 : -1 };break;
    }

    // when 'name' is like '123', `data('name')` return number 123 
    $('.dir-item').each(function() {
        dir_list.push({'name':$(this).attr('data-name'), 'time':$(this).data('time'), 'element':this});
    });
    $('.file-item').each(function() {
        file_list.push({'name':$(this).attr('data-name'), 'time':$(this).data('time'), 'element':this});
    });

    dir_list.sort(by);
    file_list.sort(by);

    $('.dir-item, .file-item').detach();

    $(dir_list).each(function(index, item) {
        table.append(item.element);
    });
    $(file_list).each(function(index, item) {
        table.append(item.element);
    });
  
    $(this).addClass('hide');
    var other;
    if (id.indexOf('up') != -1) {
        other = $('#' + id.replace('up', 'down'));
    } else {
        other = $('#' + id.replace('down', 'up'));
    }
    other.removeClass('hide');
}

var loading_icon = '<img src="{{MEDIA_URL}}img/loading-icon.gif" alt="" class="vam" />';
// cur_path: will be updated after reqDirdata
var cur_path = "{{ path|safe }}"; {# safe is for ''', '&' included in path #}

// '.dir-link' click handler
function dirlinkClick() {
    var link = $(this);

    // add loading icon
    if (link.parent().attr('class') == 'dirent-name') {
        // link is in repo-file-list
        link.parents('.dir-item').children('.dirent-icon').html(loading_icon);
    } else {
        // link is in '.path'
        var path = $('.path');
        // check if loading_icon is already there, in case some users may repeatly click the link
        if (path.find('img').length == 0) {
            path.append(' ' + loading_icon);
        }
    }
    var url_search = link.attr('href').substr(link.attr('href').indexOf('?'));
    reqDirData('{% url 'repo_dir_data' repo.id %}' + url_search, changeLocation);
    return false;
}
function changeLocation(data) {
    if (window.history.pushState) {
        window.history.pushState({'path': e(data['path'])},'','?p=' + e(data['path'])); // the 3rd argument is a relative url
    }
}

// choose featured filetype
$('.set-file-type').click(function() {
   var file_name = $('#add-new-file-form input[name="name"]');
   file_name.val('.' + $(this).data('filetype'));
   setCaretPos(file_name[0], 0);
   file_name.focus();
});

function opOnDirent(context) { // added param 'context' for 'more' dirents requested with 'list_dir_more'
    var context = context || $('.dir-item, .file-item');

// select
$('.checkbox-orig', context).unbind();
$('.select', context).click(function() {
    var dirents_op = $('#dirents-op');

    $(this).find('.checkbox').toggleClass('checkbox-checked');

    // show buttons or not
    if ($('.checkbox-checked', $('.dir-item, .file-item')).length > 0) {
        dirents_op.removeClass('hide');
        setDirentsOpPos();
    } else {
        dirents_op.addClass('hide');
    }
});

$('.dir-link', context).click(dirlinkClick);

{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}

$('.file-download').click(function() {
    var file_name = $(this).parents('tr').attr('data-name'),
        file_id = $(this).attr('data-fileid'); // data() will convert values, for example, '000000000...' is converted to 0

    var download = function(blk_arr) {
        var fileAsBlob = new Blob(blk_arr, {type:''});
        var URL = window.URL || window.webkitURL;
        var url = URL.createObjectURL(fileAsBlob);
        var link = $("<a>").attr("href", url).attr("download", file_name).html('Download').appendTo("body").hide();
        link[0].click();
        link.remove();
        showMsg("{% trans "Done!" %}", 'info');
        setTimeout(function() { $('.messages').addClass('hide'); }, 1500);
    };

    // if file size is 0, directly download it
    if (file_id == '0000000000000000000000000000000000000000') {
        download([]);
        return false;
    }
    
    showMsg("{% trans "Downloading..." %}", 'info');

    $.ajax({
        url: '{{SITE_ROOT}}ajax/repo/{{repo.id}}/encrypted_file/' + file_id + '/download/',
        dataType: 'json',
        success: function(data) {
            var block_id_list = data['blklist'],
                block_get_url_root = data['url']; 

            var blocks = [], decrypted_blocks = [];

            for (var i = 0, len = block_id_list.length; i < len; i++) {
                reqBlock(i);
            }

            var str2ab = function(str) {
                var buf = new ArrayBuffer(str.length);
                var bufView = new Uint8Array(buf);
                for (var i = 0, strLen = str.length; i < strLen; i++) {
                    bufView[i] = str.charCodeAt(i);
                }   
                return buf;
            }; 

            function reqBlock(index) {
                $.ajax({
                    url: block_get_url_root + block_id_list[index],
                    beforeSend:function(xhr) {
                        // let JQuery not process the returned binary data: return binary str
                        xhr.overrideMimeType("text/plain; charset=x-user-defined");
                    },
                    success: function(data, textStatus, xhr) {
                        blocks.push({index: index, block: str2ab(data)});
                        var msg = "{% trans "Downloading, %(num)s% complete." %}";
                        showMsg(msg.replace('%(num)s', (blocks.length / block_id_list.length * 100).toFixed(0)), 'info');
                        if (blocks.length == block_id_list.length) {
                            // after receiving all blocks
                            decrypt(blocks);
                        }
                    },
                    error: function() {
                        console.log('failed to get block ' + index);
                    }
                });
            }

            var workers = [], workersCount = 4, i;
            for (i = 0; i < workersCount; i++) {
                workers.push(new Worker('{{MEDIA_URL}}js/file_crypto.js'));
            }
            for (i = 0; i < workers.length; i++){
                workers[i].addEventListener('message', onWorkerMessage, false);
            } 
            function decrypt(blocks) {
                showMsg("{% trans "Decrypting..." %}", 'info');
                for (i = 0; i < blocks.length; i++) {
                    workers[i % workers.length].postMessage({
                        decrypt: true,
                        key: enc_key,
                        iv: enc_iv,
                        index: blocks[i].index,
                        block: blocks[i].block
                    });
                }
            }
            function onWorkerMessage(e) {
                if (typeof e.data != 'object') {
                    // error
                    return;
                }
                decrypted_blocks.push({index: e.data.index, block: e.data.block}); 
                var msg = "{% trans "Decrypting, %(num)s% complete." %}";
                showMsg(msg.replace('%(num)s', (decrypted_blocks.length / block_id_list.length * 100).toFixed(0)), 'info');
                if (decrypted_blocks.length == block_id_list.length ) {
                    onFinish();
                }
            }

            function onFinish() {
                var ordered_decrypted_blocks = [];
                for (var i = 0, len = decrypted_blocks.length; i < len; i++) {
                    ordered_decrypted_blocks[decrypted_blocks[i].index] = wordArray2ab(decrypted_blocks[i].block);
                }
                download(ordered_decrypted_blocks);
            } // onFinish ends
        }
    });
    return false;
});
{% endif %}

var popup_tr = ''; // the tr which the shown popup belongs to
$('#main-panel').removeClass('ovhd');
// to fix 'height becomes 0 after sort' for some versions of chrome/ff.
$('.hidden-op', context).each(function() {
    $(this).height($(this).height());
});
$('.more-op-icon', context).click(function() {
    var icon = $(this),
        hidden_op = icon.next();
    if (icon.attr('data')) { // no popup
        if (icon.position().left + icon.width() + hidden_op.outerWidth() < icon.parent().width()) {
            hidden_op.css({'left': icon.position().left + icon.width() + 5});
            if (icon.offset().top + hidden_op.height() <= $('#main').offset().top + $('#main').height()) {
                hidden_op.css('top', 6);
            } else {
                hidden_op.css('bottom', 2);
            }
        } else {
            hidden_op.css({'right':0});
            if (icon.offset().top + hidden_op.height() <= $('#main').offset().top + $('#main').height()) {
                hidden_op.css('top', icon.position().top + icon.height() + 3);
            } else {
                hidden_op.css('bottom', icon.position().top + icon.height() + 3);
            }
        }
        hidden_op.removeClass('hide');
        icon.attr('data','');
        no_file_op_popup = false;
        $('.dirent-op').data('popup_tr', icon.parents('tr'));
    } else {
        hidden_op.addClass('hide');
        icon.attr('data','no-popup');
        no_file_op_popup = true;
        $('.dirent-op').data('popup_tr', '');
    }
});
$(document).click(function(e) {
    var target =  e.target || event.srcElement;
    var popup_tr = $('.dirent-op').data('popup_tr');

    if (!no_file_op_popup &&
        !$('.more-op-icon, .hidden-op').is(target) &&
        !$('.hidden-op').find('*').is(target)) {
        $('.hidden-op').addClass('hide');
        $('.more-op-icon').attr('data', 'no-popup');
        no_file_op_popup = true;
        if (!popup_tr.find('*').is(target)) {
            popup_tr.removeClass('hl').find('.repo-file-op').addClass('vh'); // clicked place: the first tr, place out of the table
            $('.dirent-op').data('popup_tr', '');
            $('tr:gt(0)').each(function() { // when other tr is clicked
                if ($(this).find('*').is(target)) {
                    $(this).addClass('hl').find('.repo-file-op').removeClass('vh');
                }
            });
        }
    }
});

$('.hidden-op li', context).hover(
    function() {
        $(this).css('background', '#eee');
    },
    function() {
        $(this).css('background', '#fff');
    }
);
$('.dir-del, .file-del', context).click(function() {
    var dirent = $(this).parents('tr'),
        dirent_name = dirent.attr('data-name'),
        url_main;
    if ($(this).hasClass('dir-del')) {
        url_main = '{% url 'delete_dir' repo.id %}';
    } else {
        url_main = '{% url 'delete_file' repo.id %}';
    }

    $.ajax({
        url: url_main + '?parent_dir=' + e(cur_path) + '&name=' + e(dirent_name),
        dataType: 'json',
        success: function(data) {
            if (data['success']) {
                dirent.remove();
                no_file_op_popup = true;// make other items can work normally when hover
                var msg = "{% trans "Successfully deleted %(name)s" %}";
                msg = msg.replace('%(name)s', dirent_name);
                feedback(msg, 'success'); 
                updateCmt();
            }
        },
        error: ajaxErrorHandler
    });
    return false;
});

$('.file-rename, .dir-rename', context).click(function () {
    var op = $(this),
        dirent = op.parents('tr'),
        form = $('#rename-form'),
        orig_name = dirent.attr('data-name'), // use 'attr' instead of 'data' for cases that numbers are taken as file/dir name
        op_detail = $('.detail', form);
    form.data('op_obj', dirent).modal();

    op_detail.html(op_detail.html().replace('%(name)s', '<span class="op-target">' + orig_name + '</span>'));
    $('input[name*="name"]', form).val(orig_name);
    if (op.hasClass('file-rename')) {
        form.prepend("<h3>{% trans "Rename File" %}</h3>").data('obj_type', 'file');
    } else {
        form.prepend("<h3>{% trans "Rename Directory" %}</h3>").data('obj_type', 'dir');
    }

    $('#simplemodal-container').css({'width':'auto', 'height':'auto'});
    $(window).resize();// make the popup in the center of the window
    return false;
});

$('.file-cp, .file-mv, .dir-cp, .dir-mv', context).click(function () {
    var op = $(this), op_type, op_detail,
        dirent = op.parents('tr'),
        obj_name = dirent.attr('data-name'), obj_type,
        form = $('#mv-form'), form_hd;

    form.modal({appendTo:'#main', autoResize:true, focus:false});
    $('#simplemodal-container').css({'width':'auto', 'height':'auto'});

    if (op.hasClass('file-cp')) {
        form_hd = "{% trans "Copy File" %}";
    } else if (op.hasClass('file-mv')) {
        form_hd = "{% trans "Move File" %}";
    } else if (op.hasClass('dir-cp')) {
        form_hd = "{% trans "Copy Directory" %}";
    } else if (op.hasClass('dir-mv')) {
        form_hd = "{% trans "Move Directory" %}";
    }
    
    if ($(this).hasClass('file-cp') || $(this).hasClass('dir-cp')) {
        op_type = 'cp';
        op_detail = "{% trans "Copy %(name)s to:" %}";
    } else {
        op_type = 'mv';
        op_detail = "{% trans "Move %(name)s to:" %}";
    }

    if ($(this).hasClass('file-cp') || $(this).hasClass('file-mv')) {
        obj_type = 'file';
    } else {
        obj_type = 'dir';
    }

    op_detail = op_detail.replace('%(name)s', '<span class="op-target">' + obj_name + '</span>');
    form.prepend('<h3>' + form_hd + '</h3><h4>' + op_detail + '</h4>');

    $('input[name="op"]', form).val(op_type);
    $('input[name="obj_type"]', form).val(obj_type);
    $('input[name="obj_name"]', form).val(obj_name);
    
    form.data('op_obj', dirent);
    render_jstree_for_cur_path();
    return false;
});

{% if repo.enc_version == 2 and not server_crypto and repo.encrypted %}
$('.dir-download', context).click(function() {
    var msg = "{% trans "Directory download is not supported in this library." %}";
    $('<p class="error">' + msg + '</p>').modal();    
    return false;
});
$('.file-update', context).click(function() {
    $('#update-file-dialog').modal();
    $('#simplemodal-container').css({'width':'auto', 'height':'auto'});

    var file_name = $(this).parents('.file-item').attr('data-name');
    var form = $('#update-file-form');
    var hd = $('#update-file-dialog .hd');
    hd.html(hd.html().replace('%(file_name)s', '<span class="op-target">' + file_name + '</span>'));

    $('input[name="target_file"]', form).val(cur_path + file_name);

    $('[type="button"]', form).click(function() {
        var file_input = $('[type="file"]', form);
        if (file_input[0].files.length == 0) {
            $('.error', form).removeClass('hide');
            return false;
        }
        var file = file_input[0].files[0];

        // prepare_fd
        file_input.remove();
        var fd = new FormData(form[0]);
        fd.append('file_size', file.size);

        $.modal.close();

        $.ajax({
            url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('update-blks'),
            cache: false,
            dataType: 'json',
            success: function(data) {
                var sb_url = data['url'] + '?head=' + $('#repo-latest-commit .commit-msg').data('cmtid');
                encAndSubmitFile(file, fd, sb_url);
            },
            error: ajaxErrorHandler
        });
    });

    return false;
});
{% else %}
$('.file-update', context).click(function() {
    var file_name = $(this).parents('.file-item').attr('data-name');
    var form = $('#update-file-form');
    var saving_tip = $('.saving-tip', form);
    var upload_success = false;
    $('#update-file-dialog').modal({
        focus:false,
        containerCss: {width:600, height:$(window).height()/2},
        onClose: function() {
            $.modal.close();
            if (upload_success) {
                reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path));
            }
        }
    });
    $('.simplemodal-wrap').css({'overflow':'auto'}); // for ie

    $('input[name="target_file"]', form).val(cur_path + file_name);
    var hd = $('#update-file-dialog .hd');
    hd.html(hd.html().replace('%(file_name)s', '<span class="op-target">' + file_name + '</span>'));

    $.ajax({
        url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('update'),
        cache: false,
        dataType: 'json',
        success: function(data) {
            // Initialize the jQuery File Upload widget:
            form.fileupload({
                url: data['url'] + '?head=' + $('#repo-latest-commit .commit-msg').data('cmtid'),
                // customize it for 'done'
                getFilesFromResponse: function (data) {
                    if (data.result) {
                        return data.result;
                    }
                },
                {% if max_upload_file_size %}
                maxFileSize: {{max_upload_file_size}}, // in bytes
                {% endif %}
                maxNumberOfFiles: 1 // only 1 file can be uploaded
            })
            .bind('fileuploadprogressall', function (e, data) {
                if (data.loaded > 0 && data.loaded == data.total) {
                    saving_tip.show();
                }
            })
            .bind('fileuploaddone', function(e, data) {
                if (data.textStatus == 'success') {
                    upload_success = true; 
                    data.result[0].uploaded = true; // for 'template_download' render
                }
            })
            .bind('fileuploadcompleted fileuploadfailed', function() {
                saving_tip.hide();
            });

            // Enable iframe cross-domain access via redirect option:
            form.fileupload(
                'option',
                'redirect',
                window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '{{ MEDIA_URL }}cors/result.html?%s')
            );
        },
        error: ajaxErrorHandler
    });
    return false;
});
{% endif %}

$('.file-star', context).click(function() {
    var op = $(this),
        status = op.data('status'),
        file_name = op.parents('.file-item').data('name'),
        post_url;

    if (status == 'unstarred') {
        post_url = '{% url 'repo_star_file' repo.id %}?file=' + e(cur_path + file_name);
    } else {
        post_url = '{% url 'repo_unstar_file' repo.id %}?file=' + e(cur_path + file_name);
    }
    
    $.ajax({
        url: post_url,
        cache: false,
        dataType: 'json',
        success:function(data) {
            if (data['success']) {
                if (status == 'starred') {
                    op.attr('class', 'file-star icon-star-empty').attr('title', "{% trans 'unstarred' %}").data('status','unstarred');
                } else {
                    op.attr('class', 'file-star icon-star').attr('title', "{% trans 'starred' %}").data('status','starred');
                }
            }
        },
        error:function(xhr, textStatus, errorThrown) {
            if (xhr.responseText) {
                feedback(jQuery.parseJSON(xhr.responseText).error, 'error');
            } else {
                feedback("{% trans "Failed. Please check the network." %}", 'error');
            }
        }
   });
});

//share
$('.file-share, .dir-share', context).click(function() {
    var op = $(this), name, aj_urls, type;
    name = op.parents('tr').attr('data-name');
    aj_urls = {
        'link': '{% url 'get_shared_link' %}?repo_id={{ repo.id }}&p=' + e(cur_path) + e(name),
        'upload-link': '{% url 'get_shared_upload_link' %}?repo_id={{ repo.id }}&p=' + e(cur_path) + e(name)
    };
    if (op.hasClass('dir-share')) {
        aj_urls['link'] += '&type=d';
        type = 'd';
    } else {
        type = 'f';
    }

    showSharePopup(op, name, aj_urls, type, cur_path);
    return false;
});

{% if not repo.encrypted and ENABLE_THUMBNAIL %}
// get thumbnails for image files
$(function() {
    var img_icons = $('.not-thumbnail');
    if (img_icons.length == 0) {
        return;
    }
    var get_thumbnail = function(i) {
        var img_icon = $(img_icons[i]),
            file_name = img_icon.closest('.file-item').attr('data-name');
        $.ajax({
            url: '{% url 'thumbnail_create' repo.id %}?path=' + e(parent_dir + file_name),
            cache: false,
            dataType: 'json',
            success: function(data) {
                img_icon.attr("src", data.thumbnail_src).load(function() {
                    $(this).removeClass("not-thumbnail").addClass("thumbnail");
                });
            },
            complete: function() {
                // cur_path may be changed. e.g., the user enter another directory
                if (i < img_icons.length - 1 && parent_dir == cur_path) {
                    get_thumbnail(++i);
                }
            }
        });
    };
    var parent_dir = cur_path;
    get_thumbnail(0);
});
{% endif %}

} //function 'opOnDirent' ends here

$('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(function() {
    var form = $(this),
        form_id = form.attr('id'),
        post_url = '', post_data = {},
        path = cur_path,
        after_op_success = function() { };

    if (form_id == 'add-new-file-form' || form_id == 'add-new-dir-form') {
        var dirent_name = $.trim(form.find('input[name="name"]').val());

        if (!dirent_name) {
            apply_form_error(form_id, "{% trans "It is required." %}");
            return false;
        }
        if (form_id == 'add-new-file-form') {
            // if it has an extension, make sure it has a name
            if (dirent_name.lastIndexOf('.') != -1 && dirent_name.substr(0, dirent_name.lastIndexOf('.')).length == 0) {
                apply_form_error(form_id, "{% trans "Only an extension there, please input a name." %}");
                return false;
            }
            post_url = '{% url 'new_file' repo.id %}?parent_dir=' + e(path);
            after_op_success = function(data) {
                location.href = '{% url 'repo_view_file' repo.id %}?p=' + e(path) + e(data['name']);
            };
        } else {
            post_url = '{% url 'new_dir' repo.id %}?parent_dir=' + e(path);
            after_op_success = function(data) {
                form.append('<p style="color:red;">' + "{% trans "Creating..." %}" + '</p>');
                reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path), function() {
                    $.modal.close();
                    var new_dirent = $('#repo-file-list tr[data-name="' + data['name'] + '"]'),
                        new_dirent_pos = new_dirent.offset().top,
                        window_height = $(window).height();
                    var new_dirent_bottom = $(document).height() - new_dirent_pos;
                    $('.dirent-name a', new_dirent).css({'color':'red'});
                    if (new_dirent_pos > $(window).scrollTop() + window_height/2) {
                        if (new_dirent_bottom < window_height/2) {
                            $(window).scrollTop($(document).height() - window_height);
                        } else {
                            $(window).scrollTop(new_dirent_pos - window_height/2);
                        }
                    }
                });
            };
        }
        post_data['dirent_name'] = dirent_name;
    } else if (form_id == 'rename-form') {
        var old_name = form.find('input[name="oldname"]').val(), 
            new_name = $.trim(form.find('input[name="newname"]').val()),
            op_obj = form.data('op_obj');
        if (!new_name) {
            apply_form_error(form_id, "{% trans "It is required." %}");
            return false;
        }
        if (new_name == old_name) {
            apply_form_error(form_id, "{% trans "You have not renamed it." %}");
            return false;
        }
        if (form.data('obj_type') == 'dir') {
            post_url = '{% url 'rename_dir' repo.id %}?parent_dir=' + e(path);
        } else {
            post_url = '{% url 'rename_file' repo.id %}?parent_dir=' + e(path);
        }
        post_data['oldname'] = old_name;
        post_data['newname'] = new_name;
        after_op_success = function(data) {
            $.modal.close();
            new_name = data['newname'];
            op_obj.attr('data-name', new_name).data('time', new Date().getTime()/1000);
            updateCmt();

            var name_link = $('.dirent-name a', op_obj);
            if (name_link.length == 1) {
                name_link.html(new_name).attr('href', name_link.attr('href').substr(0, name_link.attr('href').indexOf('?')) + '?p=' + e(path+new_name));
            } else {
                $('.dirent-name', op_obj).html(new_name); // no link for files in client_crypto mode
            }
            $('.dirent-update', op_obj).html("{% trans "Just now" %}");
            var dld_link; 
            if (op_obj.attr('class') == 'dir-item') {
                dld_link = $('.dir-download', op_obj), dld_href = dld_link.attr('href'); 
                dld_link.attr('href', dld_href.substr(0, dld_href.indexOf('?')) + '?p=' + e(path+new_name));
                $('.dir-share', op_obj).attr({
                        'data-link':'',
                        'data-token':'',
                        'data-upload-link':'',
                        'data-upload-token':''
                        });
            } else {
                $('.file-star', op_obj).attr({
                    'title': "{% trans "unstarred" %}",
                    'class': 'icon-star-empty file-star',
                    'data-status': 'unstarred'
                    });
                dld_link = $('.file-download', op_obj), dld_href = dld_link.attr('href'); 
                dld_link.attr('href', dld_href.substr(0, dld_href.indexOf('?')) + '?p=' + e(cur_path + new_name));
                $('.file-share', op_obj).attr({'data-link':'', 'data-token':''});
                var file_history = $('.file-history', op_obj), fh_href = file_history.attr('href');
                file_history.attr('href', fh_href.substr(0, fh_href.indexOf('?')) + '?p=' + e(path+new_name));
            }

            var msg = "{% trans "Successfully renamed %(old_name)s to %(new_name)s" %}";
            msg = msg.replace('%(old_name)s', old_name).replace('%(new_name)s', new_name);
            feedback(msg, 'success');
        };
    } else {// #mv-form
        var dst_repo = $('[name="dst_repo"]', form).val(),
            dst_path = $('[name="dst_path"]', form).val(),
            op = $('[name="op"]', form).val(),
            obj_name = $('[name="obj_name"]', form).val(),
            obj_type = $('[name="obj_type"]', form).val(),
            op_obj = form.data('op_obj');

        if (!op_obj) { // for mv-dirents, cp-dirents
            return false;
        }

        if (!$.trim(dst_repo) || !$.trim(dst_path)) {
            $('.error', form).removeClass('hide');
            return false;
        }
        if (dst_repo == '{{repo.id }}' && (dst_path == path || (obj_type == 'dir' && dst_path == path + obj_name + '/'))) {
            $('.error', form).html("{% trans "Invalid destination path" %}").removeClass('hide');
            return false;
        }
        if (op == 'mv') {
            post_url = obj_type == 'dir' ? '{% url 'mv_dir' repo.id %}':'{% url 'mv_file' repo.id %}';
        } else {
            post_url = obj_type == 'dir' ? '{% url 'cp_dir' repo.id %}':'{% url 'cp_file' repo.id %}';
        }
        post_url += '?path=' + e(path) + '&obj_name=' + e(obj_name);
        post_data = {
            'dst_repo': dst_repo,
            'dst_path': dst_path
        };
        after_op_success = function(data) {
            $.modal.close();
            msg = data['msg'];
            if (!data['task_id']) { // no progress
                if (op=='mv') {
                    op_obj.remove();
                }
                updateCmt();
                feedback(msg, 'success');
            } else {
                var details = $('#mv-details'), 
                    cancel_btn = $('#cancel-mv'),
                    other_info = $('#mv-other-info');
                cancel_btn.removeClass('hide');
                setTimeout(function () {
                    $('#mv-progress-popup').modal({containerCss: {
                        width: 300,
                        height: 150,
                        paddingTop: 50
                    }, focus:false});
                    var det_text = op == 'mv' ? "{% trans "Moving %(name)s" %}": "{% trans "Copying %(name)s" %}";
                    details.html(det_text.replace('%(name)s', trimFilename(obj_name, 20)));
                    $('#mv-progress').progressbar();
                    req_progress();
                }, 100);
                var req_progress = function () {
                    $.ajax({
                        url: '{% url "get_cp_progress" %}?task_id=' + e(data['task_id']),
                        dataType: 'json',
                        success: function(data) {
                            var bar = $('.ui-progressbar-value', $('#mv-progress'));
                            if (!data['failed'] && !data['canceled'] && !data['successful']) {
                                if (data['done'] == data['total']) {
                                    bar.css('width', '100%'); // 'done' and 'total' can be both 0
                                    details.addClass('vh');
                                    cancel_btn.addClass('hide');
                                    other_info.html("{% trans "Saving..." %}").removeClass('hide');
                                } else {
                                    bar.css('width', parseInt(data['done']/data['total']*100, 10) + '%');
                                }
                                bar.show();
                                setTimeout(req_progress, 1000);
                            } else if (data['successful']) {
                                $.modal.close(); 
                                if (op=='mv') {
                                    op_obj.remove();
                                    updateCmt();
                                }
                                feedback(msg, 'success');
                            } else { // failed or canceled
                                details.addClass('vh');
                                var other_msg = data['failed'] ? "{% trans "Failed." %}" : "{% trans "Canceled." %}";
                                other_info.html(other_msg).removeClass('hide');
                                cancel_btn.addClass('hide');
                                setTimeout(function () { $.modal.close(); }, 1000);
                            }
                        },
                        error: function(xhr, textStatus, errorThrown) {
                            var error;
                            if (xhr.responseText) {
                                error = $.parseJSON(xhr.responseText).error;
                            } else {
                                error = "{% trans "Failed. Please check the network." %}";
                            }
                            details.addClass('vh')
                            other_info.html(error).removeClass('hide');
                            cancel_btn.addClass('hide');
                            setTimeout(function () { $.modal.close(); }, 1000); 
                        }
                    });
                };
                cancel_btn.click(function() {
                    disable(cancel_btn);
                    $.ajax({
                        url: '{% url "cancel_cp" %}?task_id=' + e(data['task_id']),
                        dataType: 'json',
                        success: function(data) {
                            details.addClass('vh')
                            other_info.html("{% trans "Canceled." %}").removeClass('hide');
                            cancel_btn.addClass('hide');
                            setTimeout(function () {$.modal.close();}, 1000);
                        },
                        error: function(xhr, textStatus, errorThrown) {
                            var error;
                            if (xhr.responseText) {
                                error = $.parseJSON(xhr.responseText).error;
                            } else {
                                error = "{% trans "Failed. Please check the network." %}";
                            }
                            other_info.html(error).removeClass('hide');
                            enable(cancel_btn);
                        }
                    });
                });
            }
        }
    }

    ajaxPost({
        'form': form,
        'post_url': post_url,
        'post_data': post_data,
        'after_op_success': after_op_success,
        'form_id': form_id
    });
    return false;
});

function ajaxPost(params) { // params: {}
    var form = params.form,
        post_url = params.post_url,
        post_data = params.post_data,
        after_op_success = params.after_op_success,
        form_id = params.form_id;
    var submit_btn = form.children('input[type="submit"]');  
    disable(submit_btn);
    $.ajax({
        url: post_url,
        type: 'POST',
        dataType: 'json',
        beforeSend: prepareCSRFToken,
        data: post_data,
        success: function(data) {
            if (data['success']) {
                after_op_success(data);
            }
        },
        error: function(xhr, textStatus, errorThrown) {
            var err;
            if (xhr.responseText) {
                err = $.parseJSON(xhr.responseText).error;
            } else {
                err = "{% trans "Failed. Please check the network." %}";
            }
            apply_form_error(form_id, err);
            enable(submit_btn);
        }
    });
}

$('#mv-dir-list .hd').click(function() {
    var span = $('span', $(this)),
        form = $('#mv-form'),
        loading_tip = $(this).next(),
        dir_tree_container = loading_tip.next().data('site_root', '{{SITE_ROOT}}'),
        file_tree = new FileTree();
    if (span.hasClass('icon-caret-right')) {
        span.attr('class','icon-caret-down');
        loading_tip.show();
        if (dir_tree_container.attr('id') == 'current-repo-dirs') {
            render_jstree_for_cur_path();
        } else {
            $.ajax({
                url: '{% url 'unenc_rw_repos' %}',
                cache: false,
                dataType: 'json',
                success: function(data) {
                    var other_repos = [];
                    for (var i = 0, len = data.length; i < len; i++) {
                        if (data[i].id != '{{repo.id}}') {
                        other_repos.push({
                            'data': data[i].name,
                            'attr': {'repo_id': data[i].id, 'root_node': true},
                            'state': 'closed'
                            });  
                        }
                    }
                    loading_tip.hide();
                    file_tree.renderDirTree(dir_tree_container, form, other_repos);
                    dir_tree_container.removeClass('hide');
                }
            });
        }
    } else {
        span.attr('class','icon-caret-right');
        dir_tree_container.addClass('hide');
    }
});
$('#private-share-form').submit(function() {
    if (!$('[name="emails"]', $(this)).val()) {
        apply_form_error($(this).attr('id'), "{% trans "Please select at least one contact." %}");
        return false;
    }
});
var last_start = 0; // for 'list_dir_more'
$(window).scroll(function() {
    var repo_top = $('#repo-top'),
        file_topbar = $('.repo-file-list-topbar'),
        repo_file_list = $('#repo-file-list'),
        list_hd = $('.repo-file-list tr:first'),
        repo_top_left = repo_top.offset().left,
        file_topbar_h = file_topbar.outerHeight(true);

    if ($(window).scrollTop() > repo_top.offset().top + repo_top.outerHeight(true) + 1) {
        repo_file_list.css({'padding-top': file_topbar_h + list_hd.outerHeight(true)});
        file_topbar.addClass('fixed-hd').css({'left': repo_top_left});  
        list_hd.addClass('fixed-hd').css({'left': repo_top_left, 'top':file_topbar_h});  
    } else {
        repo_file_list.css({'padding-top':0});
        file_topbar.removeClass('fixed-hd');  
        list_hd.removeClass('fixed-hd');  
    }

    var ele_more = $('#repo-file-list .dirent-more');
    if (ele_more.length == 1 && $(window).scrollTop() + $(window).height() >= $(document).height() - parseInt($('#repo-file-list').css('margin-bottom')) && ele_more.data('start') != last_start) {
        last_start = ele_more.data('start');
        $.ajax({
            url:'{% url 'list_dir_more' repo.id %}?p=' + e(cur_path) + '&start=' + e(ele_more.data('start')),
            dataType: 'json',
            cache: false,
            success: function(data) {
                var more_dirents = $(data['html']);
                more_dirents.appendTo($('.repo-file-list'));
                more_dirents.unbind().hover( // remove previously binded hover handler at first
                    function() {
                        if (no_file_op_popup) {
                            $(this).addClass('hl').find('.repo-file-op').removeClass('vh');
                        }
                    },
                    function() {
                        if (no_file_op_popup) {
                            $(this).removeClass('hl').find('.repo-file-op').addClass('vh');
                        }
                    }
                );
                opOnDirent(more_dirents);
                if (data['dirent_more']) {
                    ele_more.data('start', data['more_start']); 
                } else {
                    ele_more.remove();
                }
            },
            error: function(xhr, textStatus, errorThrown) {
                var error;
                if (xhr.responseText) {
                    error = $.parseJSON(xhr.responseText).error;
                } else {
                    error = "{% trans "Failed. Please check the network." %}";
                }
                ele_more.replaceWith('<p class="error">' + error + '</p>');
            }
        });
    }
});

// webkit fires 'onpopstate' when page loads, use 'setTimeout' in 'window.onload' to avoid it.
window.onload = function() {
    setTimeout(function () {
        if (window.history.pushState) {
            window.onpopstate = function(event) {
                $('.path').append(' ' + loading_icon);
                reqDirData('{% url 'repo_dir_data' repo.id %}' + location.search);
            }
        }
    }, 0);
}
function updateCmt() {
    $.ajax({
        url: '{% url 'get_current_commit' repo.id %}',
        cache: false,
        dataType: 'json',
        success: function(data) {
            $('#repo-latest-commit').html(data['html']);
            $('.lsch').click(function() {
                listCommitDetails($(this).data('url'), $(this).data('time'));
                return false;
            });
        },
        error: ajaxErrorHandler
    });
}

{% if ENABLE_SUB_LIBRARY and not repo.is_virtual %}
// private share dir submit
// only share to 1 panel(e.g. enter, groups or contacts)
   $('#share-submit-btn').click(function() {
        var form = $("#repo-share-form"),
            cur_tab_id = $('.ui-tabs-selected a', form).attr('href'),
            post_data = '',
            input = $('[name="email_or_group"]', form); 
        switch(cur_tab_id) {
            case '#share-enter':
                post_data = input.val();
                break;
            case '#share-grp-options':
            case '#share-contact-options':
                $(cur_tab_id + ' .checkbox-checked .checkbox-orig').each(function() {
                    post_data += $(this).val() + ',';
                }); 
                input.val(post_data);
        }   
        if (!post_data) {
            apply_form_error(form.attr('id'), "{% trans "Please enter emails or groups, or select some." %}");
            return false;
        }

        // check if a sub-lib exists, if not, create one
        $.ajax({
            url: '{% url 'sub_repo' repo.id %}?p=' + e(form.data('dir-path')),
            dataType: 'json',
            success: function(data) {
                $('[name="repo_id"]', form).val(data['sub_repo_id']);
                form.submit();
                disable($(this));
            },
            error: function(xhr, textStatus, errorThrown) {
                var err;
                if (xhr.responseText) {
                    err = jQuery.parseJSON(xhr.responseText).error;
                } else {
                    err = "{% trans "Failed. Please check the network." %}";
                } 
                apply_form_error(form.attr('id'), err);
            }
        });
        return false;
    });
{% endif %}

{% if not repo.encrypted and ENABLE_THUMBNAIL %}
var timer,
    default_size = {{PREVIEW_DEFAULT_SIZE}},
    preview_wrap = $('<div id="preview-wrap"><img id="image-preview" src="" alt=""/><div class="outer-caret right-outer-caret"><div class="inner-caret"></div></div></div>')
        .appendTo("body")
        .css({'width':default_size + 'px', 'height':default_size + 'px'})
        .hide(),
    image_preview = $("#image-preview"),
    caret = image_preview.next();

$("#repo-file-list").on({
    mouseenter: function() {
        var thumbnail = $('.thumbnail', $(this)),
            file_item = thumbnail.closest('.file-item');

        timer = setTimeout(function () {
            $.ajax({
            url: '{% url 'thumbnail_create' repo.id %}?path=' + e(cur_path+file_item.attr('data-name')) + '&size=' + default_size,
            cache: false,
            dataType: 'json',
            success: function(data) {
                image_preview.attr("src", data.thumbnail_src);

                var file_item_offset = file_item.offset(),
                    thumbnail_offset = thumbnail.offset(),

                    wrap_width = preview_wrap.outerWidth(),
                    wrap_padding = parseInt(preview_wrap.css('padding-top')),

                    caret_width = parseInt(caret.css('border-top-width')),
                    caret_pos_x = (default_size)/2 + wrap_padding - caret_width,
                    caret_pos_y = default_size + 2 * wrap_padding,

                    wrap_left = file_item_offset.left - wrap_width - caret_width;

                if (wrap_left >= 0) {
                    caret.removeClass('bottom-outer-caret')
                        .addClass('right-outer-caret')
                        .css({'top':caret_pos_x + 'px', 'left':caret_pos_y + 'px'});

                    preview_wrap.css({
                        'top'  : (thumbnail_offset.top + (thumbnail.height() - wrap_width)/2) + 'px',
                        'left' : wrap_left + 'px'
                    }).fadeIn();
                } else {
                    caret.removeClass("right-outer-caret")
                         .addClass("bottom-outer-caret")
                         .css({'top':caret_pos_y + 'px', 'left':caret_pos_x + 'px'});

                    preview_wrap.css({
                        'top'  : (file_item_offset.top - wrap_width) - caret_width + 'px',
                        'left' : (thumbnail_offset.left + (thumbnail.width() - wrap_width)/2) + 'px'
                    }).fadeIn();
                }
            },
            error: ajaxErrorHandler
            });
        }, 200);
    },
    mouseleave: function() {
        clearTimeout(timer);
        preview_wrap.hide();
        image_preview.attr('src', ''); // for ff. In ff, when hover, the last preview image would be shown first, then the right one.
    }
}, ".dirent-icon:has('.thumbnail')");
{% endif %}

{% include "snippets/shared_link_js.html" %}
{% include "snippets/bottom_bar.html" %} {# moved to the right side. Tue Nov 11 15:47:08 CST 2014 #}
</script>
{% endblock %}
